1 /* 2 * Copyright (c) 2011-2014 - Mauro Carvalho Chehab 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License as published by 6 * the Free Software Foundation version 2.1 of the License. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU Lesser General Public License for more details. 12 * 13 * You should have received a copy of the GNU Lesser General Public License 14 * along with this program; if not, write to the Free Software 15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 16 * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html 17 */ 18 19 module libdvbv5_d.dvb_scan; 20 21 import libdvbv5_d.dvb_fe: dvb_v5_fe_parms; 22 import libdvbv5_d.dvb_file: dvb_entry; 23 import libdvbv5_d.dvb_v5_std: dvb_sat_polarization; 24 import libdvbv5_d.pat: dvb_table_pat_program, dvb_table_pat; 25 import libdvbv5_d.nit: dvb_table_nit; 26 import libdvbv5_d.pmt: dvb_table_pmt; 27 import libdvbv5_d.sdt: dvb_table_sdt; 28 import libdvbv5_d.vct: atsc_table_vct; 29 30 extern (C): 31 32 /** 33 * @file dvb-scan.h 34 * @ingroup frontend_scan 35 * @brief Provides interfaces to scan programs inside MPEG-TS digital TV streams. 36 * @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1) 37 * @author Mauro Carvalho Chehab 38 * 39 * @par Bug Report 40 * Please submit bug reports and patches to linux-media@vger.kernel.org 41 */ 42 43 /* According with ISO/IEC 13818-1:2007 */ 44 45 enum MAX_TABLE_SIZE = 1024 * 1024; 46 47 // struct dvb_entry; 48 49 /** 50 * @struct dvb_v5_descriptors_program 51 * @brief Associates PMT with PAT tables 52 * @ingroup frontend_scan 53 * 54 * @param pat_pgm pointer for PAT descriptor 55 * @param pmt pointer for PMT descriptor 56 */ 57 struct dvb_v5_descriptors_program 58 { 59 // struct dvb_table_pat_program; 60 dvb_table_pat_program* pat_pgm; 61 // struct dvb_table_pmt; 62 dvb_table_pmt* pmt; 63 } 64 65 /** 66 * @struct dvb_v5_descriptors 67 * @brief Contains the descriptors needed to scan the Service ID and other relevant info at a MPEG-TS Digital TV stream 68 * @ingroup frontend_scan 69 * 70 * @param delivery_system Delivery system of the parsed MPEG-TS 71 * @param entry struct dvb_entry pointer (see dvb-file.h) 72 * @param pat PAT table descriptor pointer (table ID 0x00). 73 * @param vct VCT table descriptor pointer (either table ID 0xc8, 74 * for TVCT or table ID 0xc9, for CVCT) 75 * @param program PAT/PMT array associated programs found at MPEG-TS 76 * @param num_program Number of program entries at @ref program array. 77 * @param nit NIT table descriptor pointer for table ID 0x40. 78 * @param sdt SDT table descriptor pointer for table ID 0x42. 79 * @param other_nits Contains an array of pointers to the other NIT 80 * extension tables identified by table ID 0x41. 81 * @param num_other_nits Number of NIT tables at @ref other_nits array. 82 * @param other_sdts Contains an array of pointers to the other NIT 83 * extension tables identified by table ID 0x46. 84 * @param num_other_sdts Number of NIT tables at @ref other_sdts array. 85 * 86 * Those descriptors are filled by the scan routines when the tables are 87 * found. Otherwise, they're NULL. 88 * 89 * @note: Never alloc this struct yourself. This is meant to always be 90 * allocated via dvb_scan_alloc_handler_table() or via dvb_get_ts_tables(). 91 */ 92 struct dvb_v5_descriptors 93 { 94 uint delivery_system; 95 96 dvb_entry* entry; 97 uint num_entry; 98 99 // struct dvb_table_pat; 100 dvb_table_pat* pat; 101 // struct atsc_table_vct; 102 atsc_table_vct* vct; 103 dvb_v5_descriptors_program* program; 104 // struct dvb_table_nit; 105 dvb_table_nit* nit; 106 // struct dvb_table_sdt; 107 dvb_table_sdt* sdt; 108 109 uint num_program; 110 111 dvb_table_nit** other_nits; 112 uint num_other_nits; 113 114 dvb_table_sdt** other_sdts; 115 uint num_other_sdts; 116 } 117 118 /** 119 * @struct dvb_table_filter 120 * @brief Describes the PES filters used by DVB scan 121 * @ingroup frontend_scan 122 * 123 * @param tid Table ID 124 * @param pid Program ID 125 * @param ts_id Table section ID (for multisession filtering). If no 126 * specific table section is needed, -1 should be used 127 * @param table pointer to a pointer for the table struct to be filled 128 * @param allow_section_gaps Allow non-continuous section numbering 129 * @param priv Internal structure used inside the DVB core. shouldn't 130 * be touched externally. 131 */ 132 struct dvb_table_filter 133 { 134 /* Input data */ 135 ubyte tid; 136 ushort pid; 137 int ts_id; 138 void** table; 139 140 int allow_section_gaps; 141 142 /* 143 * Private temp data used by dvb_read_sections(). 144 * Should not be filled outside dvb-scan.c, as they'll be 145 * overrided 146 */ 147 void* priv; 148 } 149 150 /** 151 * @brief deallocates all data associated with a table filter 152 * @ingroup frontend_scan 153 * 154 * @param sect table filter pointer 155 */ 156 void dvb_table_filter_free (dvb_table_filter* sect); 157 158 /** 159 * @brief read MPEG-TS tables that comes from a DTV card 160 * @ingroup frontend_scan 161 * 162 * @param parms pointer to struct dvb_v5_fe_parms created when the 163 * frontend is opened 164 * @param dmx_fd an opened demux file descriptor 165 * @param tid Table ID 166 * @param pid Program ID 167 * @param table pointer to a pointer for the table struct to be filled 168 * @param timeout Limit, in seconds, to read a MPEG-TS table 169 * 170 * This function is used to read the DVB tables by specifying a table ID and 171 * a program ID. The libdvbv5 should have a parser for the descriptors of the 172 * table type that should be parsed. 173 * The table will be automatically allocated on success. 174 * The function will read on the specified demux and return when reading is 175 * done or an error has occurred. If table is not NULL after the call, it has 176 * to be freed with the apropriate free table function (even if an error has 177 * occurred). 178 * 179 * If the application wants to abort the read operation, it can change the 180 * value of parms->p.abort to 1. 181 * 182 * Returns 0 on success or a negative error code. 183 * 184 * Example usage: 185 * @code 186 * struct dvb_table_pat *pat; 187 * int r = dvb_read_section( parms, dmx_fd, DVB_TABLE_PAT, DVB_TABLE_PAT_PID, 188 * (void **) &pat, 5 ); 189 * if (r < 0) 190 * dvb_logerr("error reading PAT table"); 191 * else { 192 * // do something with pat 193 * } 194 * if (pat) 195 * dvb_table_pat_free( pat ); 196 * @endcode 197 */ 198 int dvb_read_section ( 199 dvb_v5_fe_parms* parms, 200 int dmx_fd, 201 ubyte tid, 202 ushort pid, 203 void** table, 204 uint timeout); 205 206 /** 207 * @brief read MPEG-TS tables that comes from a DTV card 208 * with an specific table section ID 209 * @ingroup frontend_scan 210 * 211 * @param parms pointer to struct dvb_v5_fe_parms created when the 212 * frontend is opened 213 * @param dmx_fd an opened demux file descriptor 214 * @param tid Table ID 215 * @param pid Program ID 216 * @param ts_id Table section ID (for multisession filtering). If no 217 * specific table section is needed, -1 should be used 218 * @param table pointer to a pointer for the table struct to be filled 219 * @param timeout limit, in seconds, to read a MPEG-TS table 220 * 221 * This is a variant of dvb_read_section() that also seeks for an specific 222 * table section ID given by ts_id. 223 */ 224 int dvb_read_section_with_id ( 225 dvb_v5_fe_parms* parms, 226 int dmx_fd, 227 ubyte tid, 228 ushort pid, 229 int ts_id, 230 void** table, 231 uint timeout); 232 233 /** 234 * @brief read MPEG-TS tables that comes from a DTV card 235 * @ingroup frontend_scan 236 * 237 * @param parms pointer to struct dvb_v5_fe_parms created when the 238 * frontend is opened 239 * @param dmx_fd an opened demux file descriptor 240 * @param sect section filter pointer 241 * @param timeout limit, in seconds, to read a MPEG-TS table 242 * 243 * This is a variant of dvb_read_section() that uses a struct dvb_table_filter 244 * to specify the filter to use. 245 */ 246 int dvb_read_sections ( 247 dvb_v5_fe_parms* parms, 248 int dmx_fd, 249 dvb_table_filter* sect, 250 uint timeout); 251 252 /** 253 * @brief allocates a struct dvb_v5_descriptors 254 * @ingroup frontend_scan 255 * 256 * @param delivery_system Delivery system to be used on the table 257 * 258 * At success, returns a pointer. NULL otherwise. 259 */ 260 dvb_v5_descriptors* dvb_scan_alloc_handler_table (uint delivery_system); 261 262 /** 263 * @brief frees a struct dvb_v5_descriptors 264 * @ingroup frontend_scan 265 * 266 * @param dvb_scan_handler pointer to the struct to be freed. 267 */ 268 void dvb_scan_free_handler_table (dvb_v5_descriptors* dvb_scan_handler); 269 270 /** 271 * @brief Scans a DVB stream, looking for the tables needed to 272 * identify the programs inside a MPEG-TS 273 * @ingroup frontend_scan 274 * 275 * @param parms pointer to struct dvb_v5_fe_parms created when 276 * the frontend is opened 277 * @param dmx_fd an opened demux file descriptor 278 * @param delivery_system delivery system to be scanned 279 * @param other_nit use alternate table IDs for NIT and other tables 280 * @param timeout_multiply improves the timeout for each table reception 281 * by using a value that will multiply the wait 282 * time. 283 * 284 * Given an opened frontend and demux, this function seeks for all programs 285 * available at the transport stream, and parses the following tables: 286 * PAT, PMT, NIT, SDT (and VCT, if the delivery system is ATSC). 287 * 288 * On sucess, it returns a pointer to a struct dvb_v5_descriptors, that can 289 * either be used to tune into a service or to be stored inside a file. 290 */ 291 dvb_v5_descriptors* dvb_get_ts_tables ( 292 dvb_v5_fe_parms* parms, 293 int dmx_fd, 294 uint delivery_system, 295 uint other_nit, 296 uint timeout_multiply); 297 298 /** 299 * @brief frees a struct dvb_v5_descriptors 300 * @ingroup frontend_scan 301 * 302 * @param dvb_desc pointed to the structure to be freed. 303 * 304 * This function recursively frees everything that is allocated by 305 * dvb_get_ts_tables() and stored at dvb_desc, including dvb_desc itself. 306 */ 307 void dvb_free_ts_tables (dvb_v5_descriptors* dvb_desc); 308 309 /** 310 * @brief Callback for the application to show the frontend status 311 * @ingroup frontend_scan 312 * 313 * @param args a pointer, opaque to libdvbv5, to be used by the 314 * application if needed. 315 * @param parms pointer to struct dvb_v5_fe_parms created when the 316 * frontend is opened 317 */ 318 alias check_frontend_t = int function (void* args, dvb_v5_fe_parms* parms); 319 320 /** 321 * @brief Scans a DVB dvb_add_scaned_transponder 322 * @ingroup frontend_scan 323 * 324 * @param parms pointer to struct dvb_v5_fe_parms created when the 325 * frontend is opened 326 * @param entry DVB file entry that corresponds to a transponder to be 327 * tuned 328 * @param dmx_fd an opened demux file descriptor 329 * @param check_frontend a pointer to a function that will show the frontend 330 * status while tuning into a transponder 331 * @param args a pointer, opaque to libdvbv5, that will be used when 332 * calling check_frontend. It should contain any parameters 333 * that could be needed by check_frontend. 334 * @param other_nit Use alternate table IDs for NIT and other tables 335 * @param timeout_multiply Improves the timeout for each table reception, by 336 * 337 * This is the function that applications should use when doing a transponders 338 * scan. It does everything needed to fill the entries with DVB programs 339 * (virtual channels) and detect the PIDs associated with them. 340 * 341 * A typical usage is to after open a channel file, open a dmx_fd and open 342 * a frontend. Then, seek for the MPEG tables on all the transponder 343 * frequencies with: 344 * 345 * @code 346 * for (entry = dvb_file->first_entry; entry != NULL; entry = entry->next) { 347 * struct dvb_v5_descriptors *dvb_scan_handler = NULL; 348 * 349 * dvb_scan_handler = dvb_scan_transponder(parms, entry, dmx_fd, 350 * &check_frontend, args, 351 * args->other_nit, 352 * args->timeout_multiply); 353 * if (parms->abort) { 354 * dvb_scan_free_handler_table(dvb_scan_handler); 355 * break; 356 * } 357 * if (dvb_scan_handler) { 358 * dvb_store_channel(&dvb_file_new, parms, dvb_scan_handler, 359 * args->get_detected, args->get_nit); 360 * dvb_scan_free_handler_table(dvb_scan_handler); 361 * } 362 * } 363 * @endcode 364 */ 365 dvb_v5_descriptors* dvb_scan_transponder ( 366 dvb_v5_fe_parms* parms, 367 dvb_entry* entry, 368 int dmx_fd, 369 check_frontend_t check_frontend, 370 void* args, 371 uint other_nit, 372 uint timeout_multiply); 373 374 /** 375 * @brief Add new transponders to a dvb_file 376 * @ingroup frontend_scan 377 * 378 * @param parms pointer to struct dvb_v5_fe_parms created when the 379 * frontend is opened 380 * @param dvb_scan_handler pointer to a struct dvb_v5_descriptors containing 381 * scaned MPEG-TS 382 * @param first_entry first entry of a DVB file struct 383 * @param entry current entry on a DVB file struct 384 * 385 * When the NIT table is parsed, some new transponders could be described 386 * inside. This function adds new entries to a dvb_file struct, pointing 387 * to those new transponders. It is used inside the scan loop, as shown at 388 * the dvb_scan_transponder(), to add new channels. 389 * 390 * Example: 391 * @code 392 * for (entry = dvb_file->first_entry; entry != NULL; entry = entry->next) { 393 * struct dvb_v5_descriptors *dvb_scan_handler = NULL; 394 * 395 * dvb_scan_handler = dvb_scan_transponder(parms, entry, dmx_fd, 396 * &check_frontend, args, 397 * args->other_nit, 398 * args->timeout_multiply); 399 * if (parms->abort) { 400 * dvb_scan_free_handler_table(dvb_scan_handler); 401 * break; 402 * } 403 * if (dvb_scan_handler) { 404 * dvb_store_channel(&dvb_file_new, parms, dvb_scan_handler, 405 * args->get_detected, args->get_nit); 406 * dvb_scan_free_handler_table(dvb_scan_handler); 407 * 408 * dvb_add_scaned_transponders(parms, dvb_scan_handler, 409 * dvb_file->first_entry, entry); 410 * 411 * dvb_scan_free_handler_table(dvb_scan_handler); 412 * } 413 * } 414 * @endcode 415 */ 416 void dvb_add_scaned_transponders ( 417 dvb_v5_fe_parms* parms, 418 dvb_v5_descriptors* dvb_scan_handler, 419 dvb_entry* first_entry, 420 dvb_entry* entry); 421 422 /* 423 * Some ancillary functions used internally inside the library, used to 424 * identify duplicated transport streams and add new found transponder entries 425 */ 426 int dvb_estimate_freq_shift (dvb_v5_fe_parms* parms); 427 428 int dvb_new_freq_is_needed ( 429 dvb_entry* entry, 430 dvb_entry* last_entry, 431 uint freq, 432 dvb_sat_polarization pol, 433 int shift); 434 435 dvb_entry* dvb_scan_add_entry ( 436 dvb_v5_fe_parms* parms, 437 dvb_entry* first_entry, 438 dvb_entry* entry, 439 uint freq, 440 uint shift, 441 dvb_sat_polarization pol); 442 443 int dvb_new_entry_is_needed ( 444 dvb_entry* entry, 445 dvb_entry* last_entry, 446 uint freq, 447 int shift, 448 dvb_sat_polarization pol, 449 uint stream_id); 450 451 dvb_entry* dvb_scan_add_entry_ex ( 452 dvb_v5_fe_parms* parms, 453 dvb_entry* first_entry, 454 dvb_entry* entry, 455 uint freq, 456 uint shift, 457 dvb_sat_polarization pol, 458 uint stream_id); 459 460 void dvb_update_transponders ( 461 dvb_v5_fe_parms* parms, 462 dvb_v5_descriptors* dvb_scan_handler, 463 dvb_entry* first_entry, 464 dvb_entry* entry);